import datetime

from django_filters import FilterSet, filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.viewsets import GenericViewSet

from api import models
from api.extension.auth import TokenAuthentication
from api.extension.mixins import DigCreateModelMixin, DigListModelMixin
from api.serializers.comment import CreateCommentSerializer, ListCommentSerializer


class CommentFilterSet(FilterSet):
    news = filters.NumberFilter(field_name='news', required=True)
    latest_id = filters.DateTimeFilter(field_name='descendant_update_datetime', lookup_expr='lte')

    class Meta:
        model = models.Comment
        fields = ["latest_id", 'news']


"""
1.先根据后代的更新时间，进行排序，获取根评论 10。
2.这些根评论关联的子评论，并构造父子关系。
"""


class CommentView(DigListModelMixin, DigCreateModelMixin, GenericViewSet):
    """ 评论 """
    filter_backends = [DjangoFilterBackend]
    filterset_class = CommentFilterSet

    # 登录认证
    authentication_classes = [TokenAuthentication, ]

    # ?news=2  ->  news=2
    # 获取某条新闻资讯的 根评论（根据后代更新时间排序）
    queryset = models.Comment.objects.filter(depth=0).order_by("-descendant_update_datetime")
    serializer_class = CreateCommentSerializer

    def perform_create(self, serializer):
        # 这个是被回复的评论id
        reply = serializer.validated_data.get('reply')
        # 没有被回复记录，也就是 根评论
        if not reply:
            # 如果是根评论 'news', "reply", "content"
            instance = serializer.save(user=self.request.user)
        else:
            # 有被回复记录，是子评论

            # 被回复的评论的root是null----说明被回复的评论就是 根评论
            #               不是null----那就获取 根评论
            if not reply.root:
                root = reply
            else:
                root = reply.root
            # 创建评论，记录深度=当前评论深度+1
            instance = serializer.save(user=self.request.user, depth=reply.depth + 1, root=root)

            # 根评论的最新更新时间
            root.descendant_update_datetime = datetime.datetime.now()
            root.save()
        instance.news.comment_count += 1
        instance.news.save()

    # 根据请求方式不同，使用的序列化器不同
    def get_serializer_class(self):
        if self.request.method == "GET":
            return ListCommentSerializer
        return CreateCommentSerializer

    # post请求，才使用 登录认证 限制，不然就允许访问
    def get_authenticators(self):
        if self.request.method == "POST":
            return super().get_authenticators()
        return []
